package com.romotc.joyin.bean;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang.StringUtils;

import com.romotc.oschina.db.DBManager;
import com.romotc.qqrobot.bean.MemberCustServiceService;
import com.romotc.qqrobot.bean.QQLogedin;
import com.romotc.qqrobot.bean.QQTask;
import com.romotc.qqrobot.bean.QQUserFriend;
import com.romotc.qqrobot.bean.QQUserFriendService;
import com.romotc.qqrobot.bean.RobotUser;
import com.romotc.qqrobot.bean.RobotUserService;
import com.romotc.qqrobot.bean.RobotUserSubQq;
import com.romotc.qqrobot.bean.RobotUserSubQqService;
import com.romotc.qqrobot.webqq.bean.Get_friend_uin_ResponseBody_result;
import com.romotc.scache.RequestSpy;

public class CustomerService {

	private static Customer cust = new Customer();
	/**
	 * 检查腾讯返回的好友：
	 * 如果在客户信息中存在则设置上custId上
	 * 如果为不存在则增加相应的客户
	 * @param userFriendList
	 * @param reqId 
	 */
	public static List<Customer> checkCustomers(List<QQUserFriend> userFriendList, RequestSpy reqSpy) {
		if(userFriendList == null || userFriendList.size() < 1) {
			return null;
		}
		
		List<Customer> newCustList = new ArrayList<Customer>();
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss~SS");
		Date cur = new Date();
		String curTimeStr = fmt.format(cur);
		
		QQLogedin curQQ = QQLogedin.getCurQqLogedIn(reqSpy);
		
		for(QQUserFriend userFriend : userFriendList) {
			if(userFriend == null)
				continue;
			
			//RomUnDo 以后要保证每个客户都有markName以防出现对应混乱
			Customer customer = qryCustomerByName(userFriend.getMarkname() == null ? 
													userFriend.getNick() : userFriend.getMarkname());
			
			if(customer == null) {
				customer = new Customer();
				fillCustomer(customer, userFriend);
				customer.setNote("登录过程中自动增加{reqId:" + reqSpy.getReqSN() + ",time:" + curTimeStr + "}");
				
				//这里直接保存会增加CustomerService.addCustomersNotExistInList的查询时间
//				newCustList.add(customer);
				long custId = saveNewCustomer(customer);
				userFriend.setCustId(custId);
				
				//客服号设置为当前登录QQ号
				customer.setCustServiceQQ(Long.valueOf(curQQ.getUin()));
			}else {
				userFriend.setCustId(-customer.getId());
				//RomUnDo 需要按照自己数据库中的分组进行设置
//				userFriend.setCategories(customer.getGroupId());
			}
		}
		
		return newCustList;
	}

	/**
	 * 根据客户名称查询客户
	 * @param custName
	 * @return
	 */
	private static Customer qryCustomerByName(String custName) {
		if(StringUtils.isBlank(custName)) {
			return null;
		}
		List<Customer> result = (List<Customer>)cust.Filter("custName = '" + custName + "'", 1, 1);
		if(result != null && !result.isEmpty()) 
			return result.get(0);
		
		return null;
	}

	/**
	 * 保持客户
	 * @param customer
	 * @return 保存成功之后对应的客户id
	 */
	private static long saveNewCustomer(Customer customer) {
		if(customer == null) 
			return -999;
		
		//RomUnDo 之前没有的客户存储过好友之后需要调用TX接口修改markName 以免QQ好友修改昵称之后该客户信息丢失
		
		return customer.Save();
		
	}

	/**
	 * 
	 * @param customer
	 * @param userFriend
	 */
	private static void fillCustomer(Customer customer, QQUserFriend userFriend) {
		if(customer == null || userFriend == null)
			return;
		
		customer.setCustName(userFriend.getMarkname() == null ? 
				userFriend.getNick() : userFriend.getMarkname());
		
//		customer.setCustServiceQQ(custServiceQQ);  没有客服号码以后处理就按照默认客服号处理
		customer.setGroupId(userFriend.getCategories());
		
	}
	
	
	public static void main(String[] args) throws Exception{
//		Customer c = qryCustomerByName("Romotc", 1);
//		System.out.println(c.getId());
		
//		scanNewCustomer();
		
		System.out.println(shortCustName("小灰【提供短信通插件】", 24));
	}

	
	/**
	 * 增加数据库中有 而腾讯好友列表中没有的
	 * @param userFriendList 腾讯好友列表
	 * @return
	 */
	public static List<QQUserFriend> addCustomersNotExistInList(
			List<QQUserFriend> userFriendList) {
		if(userFriendList == null) 
			userFriendList = new ArrayList<QQUserFriend>();
		
		Map<String, QQUserFriend> userMap = transToMap(userFriendList);
		
		int total = cust.TotalCount();
		int pageSize = total > 25 ? 25 : total;
		int count = 0;
		int page = 1;
		List<Customer> result = null;
		QQUserFriend quf;
		while(count < total) {
			result = (List<Customer> )cust.List(page, pageSize);
			if(result == null || result.isEmpty()) 
				break;
			page++;
			count += result.size();
			
			for(Customer customer : result) {
				if(customer == null)
					continue;
				
				quf = userMap.get(customer.getCustName());
				if(quf == null && StringUtils.isNotBlank(customer.getQqNum())) {
					//非QQ好友客户 且有登记QQ号码 增加相应的好友
					quf = QQUserFriend.createQUF(customer);
					userFriendList.add(quf);
				}
			}
		}
		
		return userFriendList;
	}

	/**
	 * 将list 转换成Map<markName-->nickName>,obj
	 * @param userFriendList
	 * @return
	 */
	private static Map<String, QQUserFriend> transToMap(
			List<QQUserFriend> userFriendList) {
		
		Map<String, QQUserFriend>  quMap = new HashMap<String, QQUserFriend>(); 
		if(userFriendList == null || userFriendList.isEmpty())
			return quMap;
		
		for(QQUserFriend quf : userFriendList) {
			if(quf == null)
				continue;
			
			quMap.put(quf.getMarkname() == null ? quf.getNick() : quf.getMarkname(), quf);
		}
		return quMap;
	}

	/**
	 * 将newCustList 保存到数据库中
	 * @param newCustList
	 */
	public static void saveCustomerList(List<Customer> newCustList) {
		if(newCustList == null || newCustList.isEmpty()) 
			return;
		
		
		
	}

	/**
	 * 根据客户Id 查询客户
	 * @param custId
	 * @return
	 */
	public static Customer qryCustomerById(long custId) {
		return cust.Get(custId);
	}

	/**
	 * 根据客户名称 用户号查询客户
	 * @param markname
	 * @param robotUid
	 * @return
	 */
	public static Customer qryCustomerByName(String custName, long robotUid) {
		if(StringUtils.isBlank(custName)) {
			return null;
		}
		List<Customer> result = (List<Customer>)cust
			.Filter("custName = '" + custName + "'" + " and uid = " + robotUid, 1, 1);
		if(result != null && !result.isEmpty()) 
			return result.get(0);
		
		return null;
	}

	/**
	 * 检查Qq好友与客户的对象关系
	 * 如果Qq好友的markName为空则取QQ号码 然后增加相应客户
	 * 如果markName不为空(有可能重复)：取QQ号码，检查Qq号码是否存在客户
	 * @param resBody
	 * @param task
	 */
	public static void checkFriendsAndCustomer(Get_friend_uin_ResponseBody_result resObject
				, QQTask task) throws java.sql.SQLException{
		
		QQUserFriend qUserFriend = QQUserFriendService
			.qryQFriendByUin(task.getLoginId(), task.getTaskQqUin());
		if(qUserFriend == null) {
			task.setTaskRunNote("unfound Uin QUserFriend");
			task.setTaskRunResult(task.RunResult_Error_DotTry);
		}
		//执行任务的QQ对应的用户
		long robotUid = RobotUserService.qryUidByQQNum(task.getTaskQqNum());
		if(robotUid < 0) {
			task.setTaskRunNote("unfound robotUser by taskQqNum");
			task.setTaskRunResult(task.RunResult_Error_DotTry);
		}
		
		StringBuilder runLog = new StringBuilder();
		//是否需要 设置新markName
		String newMarkName = null;
		
		//对应的客户
		Customer  cust = CustomerService.qryCustomerByQNum(robotUid, 
				String.valueOf(resObject.getAccount()));
		if(cust == null) {
			//产生与现有客户不重复的客户名
			newMarkName = CustomerService.randomNewCustName(qUserFriend, robotUid);
			//生成客户
			cust = new Customer();
			cust.setCustName(newMarkName);
			cust.setCustServiceQQ(Long.parseLong(task.getTaskQqNum()));
			cust.setNote("taskId:" + task.getId());
			cust.setQqNum(String.valueOf(resObject.getAccount()));
			cust.setUid(robotUid);
	
			cust.Save();
			runLog.append(" create new Customer id:").append(cust.getId());
			
			//重新检查是否需要修改markName
			if(newMarkName.equals(qUserFriend.getMarkname()))
				newMarkName = null;
			
		}else {
			//检查客户名称是否超长
			if(StringUtils.isBlank(cust.getCustName())) {
				newMarkName = CustomerService.randomNewCustName(qUserFriend, robotUid);

			}else {
				//客户名可能超过腾讯markName允许的最大长度
				newMarkName = shortCustName(cust.getCustName(), 24);
			}
			
			if(!newMarkName.equals(cust.getCustName())) {
				runLog.append(" custId:").append(cust.getId())
				.append("'s custName is chg by soft,reset from ").append(cust.getCustName())
					.append(" to ").append(newMarkName);
				cust.setCustName(newMarkName);
				cust.Delete();
				cust.Save();
			}
		}
		
		if(newMarkName != null) {
			//生成一个修改昵称的任务RomUnDo
			QQTask qTask = new QQTask();
			qTask.setLoginId(task.getLoginId());
			qTask.setTaskInTime();
			qTask.setTaskQqNum(task.getTaskQqNum());
			qTask.setTaskQqNum2(String.valueOf(resObject.getAccount()));
			qTask.setTaskQqUin(task.getTaskQqUin());
			qTask.setTaskType(QQTask.TaskType_ChgMarkName);
			qTask.setTaskRunNote("create by taskId:" + task.getId());
			qTask.setContent(newMarkName);
			
			qTask.Save();
			runLog.append(" create task:").append(qTask.getId());
		}
		
		//设置qufriend custId 最好用delete RomUnDo
		qUserFriend.setCustId(cust.getId());
		qUserFriend.setQqNum(String.valueOf(resObject.getAccount()));
		qUserFriend.Delete();
		qUserFriend.Save();
		
		runLog.append(" modify qUserFriendId:").append(qUserFriend.getId())
			.append(" 's custId to ").append(cust.getId()).append(" qqNum to ").append(qUserFriend.getQqNum());
		
		task.setTaskRunNote(runLog.toString());
		task.setTaskRunResult(task.RunResult_Finished);
	}

	/**
	 * 生成一个新的不重复的客户名称(汉字最多8个，英文字符24个)
	 * @param qUserFriend
	 * @return
	 */
	private static String randomNewCustName(QQUserFriend qUserFriend, long robotUid) {
		Random random = new Random();
		String newMarkName = null;
		if(StringUtils.isNotBlank(qUserFriend.getMarkname()))
			newMarkName = qUserFriend.getMarkname();
		else 
			newMarkName = qUserFriend.getNick();
		if(StringUtils.isBlank(newMarkName))
			newMarkName = String.valueOf(random.nextInt(1000));
		
		newMarkName = shortCustName(newMarkName, 21);//获得缩短后的客户名（不超过19个字符 腾讯规则中文占3个字符）
		
		String origMarkName = newMarkName;
		while(true) {
			if(qryCustomerByName(newMarkName, robotUid) == null) 
				//不与现有客户冲突
				break;
			
			//产生随机markName
			newMarkName = origMarkName + random.nextInt(1000);
		}
		
		return newMarkName;
	}

	/**
	 * 获得缩短后的客户名（不超过len个字符 腾讯规则中文占3个字符）
	 * @param newMarkName
	 * @param len
	 * @return
	 */
	public static String shortCustName(String newMarkName, int len) {
		if(StringUtils.isBlank(newMarkName))
			return "";
		
		int count = 0;
		char c;
		StringBuilder bld = new StringBuilder();
		for(int i = 0; i < newMarkName.length();i++) {
			c = newMarkName.charAt(i);
			if(c > 256)
				count += 3;//腾讯规则汉字占3个
			else //
				count++;
			
			if(count > len)
				break;
			
			String s = newMarkName.substring(i, i+1);
			bld.append(s);
		}
		
		return bld.toString();
	}

	/**
	 * 根据客户QQ号 robotUid查询客户
	 * @param robotUid
	 * @param qqNum
	 * @return
	 */
	public static Customer qryCustomerByQNum(long robotUid, String qqNum) {
		if(StringUtils.isBlank(qqNum)) {
			return null;
		}
		List<Customer> result = (List<Customer>)cust
			.Filter("qqNum = '" + qqNum + "'" + " and uid = " + robotUid, 1, 1);
		if(result != null && !result.isEmpty()) 
			return result.get(0);
		
		return null;
	}

	/**
	 * 扫描客户表新增的记录 安排合适的子号(好友数最少的)进行加好友
	 */
	public static void scanNewCustomer() throws Exception{
		// 1.查询出customer表 qqNum不为空 && custServiceQQ为空（没有加为好友） 且note字段为空(没有加入加好友任务)的记录
		                 //X不采用： 或cust....  QQ不为空(制定由哪个号加好友)
		List<Customer> newCustomers = qryNewQQCustomer(50);//最多50个
		
		if(newCustomers != null && !newCustomers.isEmpty()) {
			
			for(Customer newCust : newCustomers) {
				try {
					addNewCust2TaskList(newCust);
				} catch (Throwable e) {//有异常就回退事务
					DBManager.getConnection().rollback();
					DBManager.closeConnection();
				}finally {
					DBManager.closeConnection();
				}
			}

		}
		
	}
	
	/**
	 * 查询新增的客户
		// 1.查询出customer表 qqNum不为空 && custServiceQQ为空（没有加为好友） 且note字段为空(没有加入加好友任务)的记录
		                 //X不采用： 或cust....  QQ不为空(制定由哪个号加好友)
	 * @param maxSize
	 * @return
	 */
	public static List<Customer> qryNewQQCustomer(int maxSize) {
		String filter = "qqNum is not Null and (custServiceQQ is Null or custServiceQQ = 0) " +
				"and (note = '' or note is Null)";
		int size = cust.TotalCount(filter);
		if(size == 0)
			return null;
		size = size > maxSize ? maxSize : size;
		
		return (List<Customer>)cust.Filter(filter, 1, size);
	}

	public static void addNewCust2TaskList(Customer newCust) throws Exception{
		long uid = newCust.getUid();//归属的robot用户id
		
		//每次都查询客户数最少的子号
		RobotUserSubQq  subQQ = RobotUserSubQqService.qryMinFriendsSubQQ(uid);//好友数最少的子号
		long friendAdd2;//客户加到哪个号码上去
		if(subQQ != null) {
			
			friendAdd2 = subQQ.getQqNum();
		}else {//如果没有子号则加到主号上
			
			RobotUser robotUser = RobotUserService.qryUser(uid);
			friendAdd2 = robotUser.getSupperQNum();
		}
		
		//给其分派加好友任务
		QQTask qTask = new QQTask();
		qTask.setTaskType(qTask.TaskType_AddFriends);
		qTask.setTaskQqNum(String.valueOf(friendAdd2));
		qTask.setTaskQqNum2(newCust.getQqNum());
		qTask.Save();
		
		//分配好任务之后修改客户表
		newCust.setCustServiceQQ(friendAdd2);//X不设置该字段 这个字段是确认加上好友之后才设置的 还是设置上吧 不然TAsk中还得反查customer进行修改 而且也存在已经加了客户但是客户把机器人好友删掉的情况
		newCust.setNote("waiting to be Add by Task:" + qTask.getId());
		newCust.Delete();
		newCust.Save();
		
		//修改好友数
		if(subQQ != null) {
			subQQ.setFriendsSize(subQQ.getFriendsSize() + 1);
			subQQ.Delete();
			subQQ.Save();
		}
	}

	/**
	 * 客户 grant to CustService
	 */
	public static void grantCustomer() throws Exception{
		// 查询出来csId为空的客户(未分配客服人员) 最多100个
		List<Customer> custList = qryCustomerHasNoCustService();
		
		
		if(custList == null || custList.isEmpty())
			return;
		
		for(Customer cust : custList) {
				try {
					grantCustomer(cust);
				} catch (Exception e) {
					//有异常回滚事务
					DBManager.getConnection().setAutoCommit(false);
					DBManager.getConnection().rollback();
					DBManager.closeConnection();
					e.printStackTrace();
				}
				
				//关闭数据库连接
				DBManager.closeConnection();
				
			}
			
			
		}

	/**
	 * 查询没有客服人员的客户
	 * @return
	 */
	public static List<Customer> qryCustomerHasNoCustService() {
		String filter = "csId is Null or csId = 0";
		int size = cust.TotalCount(filter);
		return (List<Customer>)cust.Filter(filter, 1, size);
	}

	/**
	 * 为客户分配客服人员
	 * @param cust2
	 */
	public static void grantCustomer(Customer cust2) throws Exception{
		//根据Uid查询出来其下的客服人员中服务客户数最少的一个
		long uid = cust2.getUid();
		MemberCustService memCustService = MemberCustServiceService.qryMinCustsService(uid);

		//如果其下没有客服人员则setCsId -9标记为不需要客服(适用于个人用户 没有子号 没有客服号)
		if(memCustService == null) {
			cust2.setCsId(MemberCustService.Type_NeedNot);
		}else {
			//给其分配客户 insert cust_grant
			CustomerGrant custGrant = new CustomerGrant();
			custGrant.setCsId(memCustService.getId());
			custGrant.setCustId(cust2.getId());
			custGrant.setNote(custGrant.Type_AutoGrants);
			custGrant.setServiceOrder(custGrant.Order_Default);
			custGrant.setToUid(uid);
			custGrant.Save();
			
			//cust.setCsId为服务质量监督号
			cust2.setCsId(memCustService.getId());

		}
		cust2.Delete();
		cust2.Save();
		
	}

	

}
